package com.hexiang.client.impl;

import com.alibaba.csp.sentinel.EntryType;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.hexiang.client.UserHttpApiClient;
import com.hexiang.client.handler.ClientResponseHandler;
import com.hexiang.client.handler.UserHttpApiClientBlockHandler;
import com.hexiang.domain.CommonResponse;
import com.hexiang.domain.User;
import com.hexiang.exception.ClientException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

@Component
@Slf4j
public class UserHttpApiClientImpl implements UserHttpApiClient {

    private static final String USER_HTTP_URL = "https://localhost:8443";

    @Resource
    private RestTemplate slowRestTemplate;

    @Resource
    private RestTemplate restTemplate;

    @SentinelResource(value = "getUsers", entryType = EntryType.IN, blockHandlerClass = UserHttpApiClientBlockHandler.class, blockHandler = "getUsers")
    @Override
    public CommonResponse<Serializable> getUsers() throws ClientException {
        CommonResponse<Serializable> commonResponse = null;
        try {
            String url = USER_HTTP_URL + "/users";
            ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class);
            // 判断请求是否发生异常
            commonResponse = ClientResponseHandler.handleResponse("查询用户信息列表", responseEntity);
        } catch (Exception e) {
            log.error("getUsersErr", e);
            ClientResponseHandler.handleExceptionThrow("查询用户信息列表", e);
        }
        return commonResponse;
    }

    @Override
    public CommonResponse<Serializable> getUserByName(String name) throws ClientException {
        CommonResponse<Serializable> commonResponse = null;

        String url = USER_HTTP_URL + "/user/" + name;
        try {
            ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class);
            // 判断请求是否发生异常
            commonResponse = ClientResponseHandler.handleResponse("根据用户名查询用户信息", responseEntity);

        } catch (Exception e) {
            log.error("getUserByNameErr,params is {}", name, e);
            ClientResponseHandler.handleExceptionThrow("根据用户名查询用户信息", e);
        }

        return commonResponse;
    }

    @Override
    public CommonResponse<Serializable> addUser(String name, int age) throws ClientException {
        CommonResponse<Serializable> commonResponse = null;
        String url = USER_HTTP_URL + "/user";
        try {
            // 请求头设置
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

            // 提交参数设置
            MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
            map.add("name", name);
            map.add("age", String.valueOf(age));

            // 组装请求体
            HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
            ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, request, String.class);
            commonResponse = ClientResponseHandler.handleResponse("新增用户", responseEntity);

        } catch (Exception e) {
            log.error("addUserErr,params is{}", String.format("name is %s,age is %s", name, age), e);
            ClientResponseHandler.handleExceptionThrow("新增用户", e);
        }
        return commonResponse;
    }

    @Override
    public CommonResponse<Serializable> deleteUserById(Long id) throws ClientException {
        CommonResponse<Serializable> commonResponse = null;
        String url = USER_HTTP_URL + "/user/" + id;
        try {
            restTemplate.delete(url, String.class);
            commonResponse = CommonResponse.builder().succ(true).build();
        } catch (Exception e) {
            log.error("deleteUserByIdErr,params is {}", id, e);
            ClientResponseHandler.handleExceptionThrow("根据id删除用户", e);
        }
        return commonResponse;
    }

    @Override
    public CommonResponse<Serializable> updateUser(User user) throws ClientException {

        CommonResponse<Serializable> commonResponse = null;
        String url = USER_HTTP_URL + "/user/";
        try {
            restTemplate.put(url, user, String.class);
            commonResponse = CommonResponse.builder().succ(true).build();
        } catch (Exception e) {
            log.error("updateUserErr,params is {}", user, e);
            ClientResponseHandler.handleExceptionThrow("修改用户", e);
        }
        return commonResponse;
    }

    @Override
    public CommonResponse<Serializable> getUserPage(Integer pageNum, Integer pageSize) throws ClientException {

        CommonResponse<Serializable> commonResponse = null;
        String url = USER_HTTP_URL + "/user/page";
        try {
            Map<String, Object> paramMap = new HashMap<>(16);
            paramMap.put("pageNum", pageNum);
            paramMap.put("pageSize", pageSize);

            ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class, paramMap);

            // 判断请求是否发生异常
            commonResponse = ClientResponseHandler.handleResponse("分页查询用户信息", responseEntity);
        } catch (Exception e) {
            log.error("getUserPageErr,params is {}", String.format("pageNum is %s,pageSize is %s", pageNum, pageSize), e);
            ClientResponseHandler.handleExceptionThrow("分页查询用户信息", e);
        }
        return commonResponse;
    }

    @SentinelResource(value = "errTest", entryType = EntryType.IN, blockHandlerClass = UserHttpApiClientBlockHandler.class, blockHandler = "errTest")
    @Override
    public CommonResponse<Serializable> errTest() throws ClientException {
        CommonResponse<Serializable> commonResponse = null;

        try {
            String url = USER_HTTP_URL + "/user/err";
            ResponseEntity<String> responseEntity = slowRestTemplate.getForEntity(url, String.class);
            // 判断请求是否发生异常
            commonResponse = ClientResponseHandler.handleResponse("异常测试", responseEntity);
        } catch (Exception e) {
            log.error("errTestErr", e);
            ClientResponseHandler.handleExceptionThrow("异常测试", e);
        }
        return commonResponse;
    }
}